<!--
 * @Author: xcl
 * @Date: 2022-04-20 18:05:17
 * @LastEditors: Please set LastEditors
 * @LastEditTime: 2022-10-08 09:59:33
 * @Description: 视频融合
-->
<template>
  <div>
    <cesium-map @fun="fun" :opt="opt" :type="2"></cesium-map>
    <el-row type="flex" :gutter="20" class="opreate">
      <el-col :span="24">
        <div class="grid-content bg-purple">
          <el-button type="" @click="draw('point')">
            绘制点
            <p class="tips" ref="pointTips">单击左键开始、右键结束</p>
          </el-button>
          <el-button type="" @click="draw('polyline')">
            绘制线
            <p class="tips" ref="polylineTips">单击左键开始、右键结束</p>
          </el-button>
          <el-button type="" @click="draw('polygon')">
            绘制面
            <p class="tips" ref="polygonTips">单击左键开始、右键结束</p>
          </el-button>
          <el-button type="danger" @click="clearDrawEntities">
            清空
            <p class="tips danger" ref="clearTips">清空点、线、面</p>
          </el-button>
        </div>
      </el-col>
    </el-row>
  </div>
</template>

<script>
import CesiumMap from "@/components/map/CesiumMap.vue";
export default {
  name: "CesiumDraw",
  components: {
    "cesium-map": CesiumMap,
  },
  data() {
    return {
      opt: {
        view: "108.9498687298145,34.366341946514545,1627.423896875213,352.9273975440507,-88.48816732623489,0",
      },

      tempEntities: [],
    };
  },
  props: {},
  watch: {},
  created() {},
  mounted() {},
  beforeDestroy() {},
  destroyed() {},
  methods: {
    fun(viewer) {
      this.eventInteraction(viewer);
    },

    /**
     * 事件交互（鼠标移动和点击）
     * @param {*} viewer
     */
    eventInteraction(viewer) {
      let self = this;
      let handler;
      if (handler != undefined) {
        ShapeEventHandler.removeInputAction(
          Cesium.ScreenSpaceEventType.MOUSE_MOVE
        );
        ShapeEventHandler.removeInputAction(
          Cesium.ScreenSpaceEventType.LEFT_CLICK
        );
      }
      handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas);

      handler.setInputAction(function (event) {
        // console.log("移动事件：", event);
        // var pick = viewer.scene.pick(event.endPosition);
        // console.log(pick)
        // if (Cesium.defined(pick)) {
        // } else {
        // }
      }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

      // 点击
      handler.setInputAction(function (event) {
        // console.log("点击事件：", event);
        // var pick = viewer.scene.pick(event.position);
        // console.log(pick)
        // if (Cesium.defined(pick)) {
        // } else {
        // }

        // =======================================================================================
        const pickRay = viewer.camera.getPickRay(event.position);
        var cartesian = viewer.scene.globe.pick(pickRay, viewer.scene);
        // 拾取地形高度/海拔、位置信息、经纬度数据
        if (cartesian !== undefined) {
          var cartographic = Cesium.Cartographic.fromCartesian(cartesian);
          let earthPosition = viewer.camera.pickEllipsoid(
            event.position,
            viewer.scene.globe.ellipsoid
          );
          console.log("位置信息1：", earthPosition);
          var maplnglat =
            viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian);
          console.log("位置信息2：", maplnglat);
          if (Cesium.defined(earthPosition)) {
            let lon = Cesium.Math.toDegrees(cartographic.longitude).toFixed(6);
            let lat = Cesium.Math.toDegrees(cartographic.latitude).toFixed(6);
            console.log("位置信息3 - 经纬度：", lon, lat);
            let height = viewer.scene.globe.getHeight(cartographic).toFixed(3);
            console.log("地形高度/海拔：", height);
          }
        }
        // 拾取相机数据
        if (true) {
          let cheight = viewer.camera.positionCartographic.height.toFixed(2);
          console.log("相机高度数据：", cheight);
          let bestView = {
            position: {
              x: viewer.camera.positionWC.x,
              y: viewer.camera.positionWC.y,
              z: viewer.camera.positionWC.z,
            },
            // 方向 围绕Z轴旋转
            heading: Cesium.Math.toDegrees(viewer.camera.heading).toFixed(2),
            // 倾斜角度 围绕Y轴旋转
            pitch: Cesium.Math.toDegrees(viewer.camera.pitch).toFixed(2),
            // 围绕X轴旋转
            roll: Cesium.Math.toDegrees(viewer.camera.roll).toFixed(2),
          };
          console.log("相机最佳位置数据：", JSON.stringify(bestView));
        }
        // =======================================================================================
      }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
    },

    /**
     * 根据类型绘制对象
     * @param type point、polyline、polygon
     */
    draw(type) {
      //绘制点
      let that = this;
      let viewer = window.vmCesiumViewer;
      let tempEntities = this.tempEntities;
      let position = [];
      let tempPoints = [];
      // 开启深度检测
      viewer.scene.globe.depthTestAgainstTerrain = true;
      let handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
      switch (type) {
        case "point":
          // 监听鼠标左键
          handler.setInputAction(function (movement) {
            // 从相机位置通过windowPosition 世界坐标中的像素创建一条射线。返回Cartesian3射线的位置和方向。
            let ray = viewer.camera.getPickRay(movement.position);
            // 查找射线与渲染的地球表面之间的交点。射线必须以世界坐标给出。返回Cartesian3对象
            position = viewer.scene.globe.pick(ray, viewer.scene);
            let point = that.drawPoint(position);
            tempEntities.push(point);
          }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
          // 左键双击停止绘制
          // handler.setInputAction(function () {
          //   handler.destroy();//关闭事件句柄
          //   handler = null;
          // }, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
          // 右击单击停止绘制
          handler.setInputAction(function () {
            handler.destroy(); //关闭事件句柄
            handler = null;
          }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
          break;
        case "polyline":
          //鼠标移动事件
          handler.setInputAction(function (movement) {},
          Cesium.ScreenSpaceEventType.MOUSE_MOVE);
          //左键点击操作
          handler.setInputAction(function (click) {
            //调用获取位置信息的接口
            let ray = viewer.camera.getPickRay(click.position);
            position = viewer.scene.globe.pick(ray, viewer.scene);
            tempPoints.push(position);
            let tempLength = tempPoints.length;
            //调用绘制点的接口
            let point = that.drawPoint(tempPoints[tempPoints.length - 1]);
            tempEntities.push(point);
            if (tempLength > 1) {
              let pointline = that.drawPolyline([
                tempPoints[tempPoints.length - 2],
                tempPoints[tempPoints.length - 1],
              ]);
              tempEntities.push(pointline);
            } else {
              that.$refs.polylineTips.innerHTML =
                "请绘制下一个点，单击右键结束";
            }
          }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
          //右键点击操作
          handler.setInputAction(function (click) {
            tempPoints = [];
            handler.destroy(); //关闭事件句柄
            handler = null;
          }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
          break;
        case "polygon":
          //鼠标移动事件
          handler.setInputAction(function (movement) {},
          Cesium.ScreenSpaceEventType.MOUSE_MOVE);
          //左键点击操作
          handler.setInputAction(function (click) {
            //调用获取位置信息的接口
            let ray = viewer.camera.getPickRay(click.position);
            position = viewer.scene.globe.pick(ray, viewer.scene);
            tempPoints.push(position);
            let tempLength = tempPoints.length;
            //调用绘制点的接口
            let point = that.drawPoint(position);
            tempEntities.push(point);
            if (tempLength > 1) {
              let pointline = that.drawPolyline([
                tempPoints[tempPoints.length - 2],
                tempPoints[tempPoints.length - 1],
              ]);
              tempEntities.push(pointline);
            } else {
              that.$refs.polygonTips.innerHTML = "请绘制下一个点，单击右键结束";
            }
          }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
          //右键点击操作
          handler.setInputAction(function (click) {
            let cartesian = viewer.camera.pickEllipsoid(
              click.position,
              viewer.scene.globe.ellipsoid
            );

            if (cartesian) {
              let tempLength = tempPoints.length;
              if (tempLength < 3) {
                that.$refs.polygonTips.innerHTML =
                  "请选择3个以上的点再执行闭合操作命令";
              } else {
                //闭合最后一条线
                let pointline = that.drawPolyline([
                  tempPoints[tempPoints.length - 1],
                  tempPoints[0],
                ]);
                tempEntities.push(pointline);
                that.drawPolygon(tempPoints);
                tempEntities.push(tempPoints);
                handler.destroy(); //关闭事件句柄
                handler = null;
              }
            }
          }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
          break;
      }
    },
    drawPoint(position, config) {
      let viewer = window.vmCesiumViewer;
      let config_ = config ? config : {};
      return viewer.entities.add({
        name: "点几何对象",
        position: position,
        point: {
          color: Cesium.Color.SKYBLUE,
          pixelSize: 10,
          outlineColor: Cesium.Color.YELLOW,
          outlineWidth: 3,
          disableDepthTestDistance: Number.POSITIVE_INFINITY,
          heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
        },
      });
    },
    drawPolyline(positions, config_) {
      let viewer = window.vmCesiumViewer;
      if (positions.length < 1) return;
      let config = config_ ? config_ : {};
      return viewer.entities.add({
        name: "线几何对象",
        polyline: {
          positions: positions,
          width: config.width ? config.width : 5.0,
          material: new Cesium.PolylineGlowMaterialProperty({
            color: config.color
              ? new Cesium.Color.fromCssColorString(config.color)
              : Cesium.Color.GOLD,
          }),
          depthFailMaterial: new Cesium.PolylineGlowMaterialProperty({
            color: config.color
              ? new Cesium.Color.fromCssColorString(config.color)
              : Cesium.Color.GOLD,
          }),
          clampToGround: true,
        },
      });
    },
    drawPolygon(positions, config_) {
      let viewer = window.vmCesiumViewer;
      if (positions.length < 2) return;
      let config = config_ ? config_ : {};
      return viewer.entities.add({
        name: "面几何对象",
        polygon: {
          hierarchy: positions,
          material: config.color
            ? new Cesium.Color.fromCssColorString(config.color).withAlpha(0.2)
            : new Cesium.Color.fromCssColorString("#FFD700").withAlpha(0.2),
        },
      });
    },
    /**
     * 清除实体
     */
    clearDrawEntities() {
      this.$refs.polylineTips.innerHTML = "单击左键开始、右键结束";
      this.$refs.polygonTips.innerHTML = "单击左键开始、右键结束";
      let viewer = window.vmCesiumViewer;
      this.tempEntities = [];
      // 清除之前的实体
      const entitys = viewer.entities._entities._array;
      let length = entitys.length;
      // 倒叙遍历防止实体减少之后entitys[f]不存在
      for (let f = length - 1; f >= 0; f--) {
        if (
          entitys[f]._name &&
          (entitys[f]._name === "点几何对象" ||
            entitys[f]._name === "线几何对象" ||
            entitys[f]._name === "面几何对象")
        ) {
          viewer.entities.remove(entitys[f]);
        }
      }
    },
  },
};
</script>

<style lang="less" scoped>
.opreate {
  position: fixed;
  bottom: 20px;
  left: 0;
  z-index: 9999;
  width: 100%;
  text-align: center;
}

.tips {
  font-size: 12px;
  margin-top: 5px;
  color: #f56c6c;
}
.tips.danger {
  color: #606266;
}
</style>
